Skip to content

Feat/copy assets#2017

Open
joshuaunity wants to merge 11 commits intomainfrom
feat/copy-assets
Open

Feat/copy assets#2017
joshuaunity wants to merge 11 commits intomainfrom
feat/copy-assets

Conversation

@joshuaunity
Copy link
Contributor

@joshuaunity joshuaunity commented Mar 11, 2026

Description

This PR introduces an API allowing users to copy assets from one account to another, using the original account's assets as templates. The feature is currently in progress and being developed incrementally.

##TODO

  • Successfully Copy Assets to target account
  • Write a test to confirm the above feature
  • Write a test to confirm that asset parents and children are accurate
  • Successfully copy assets and asset sensors to the target account
  • Write a test to confirm the above feature
  • Successfully copy asset flexconfig... (i dont know how feasible this would be yet, mayb e 80% ?)
  • Write a test to confirm the above feature

Look & Feel

None

How to test

Further Improvements

Related Items

This PR closes #1966

Sign-off

  • I agree to contribute to the project under Apache 2 License.
  • To the best of my knowledge, the proposed patch is not based on code under GPL or other license that is incompatible with FlexMeasures

Signed-off-by: joshuaunity <oghenerobojosh01@gmail.com>
Signed-off-by: joshuaunity <oghenerobojosh01@gmail.com>
Signed-off-by: joshuaunity <oghenerobojosh01@gmail.com>
Signed-off-by: joshuaunity <oghenerobojosh01@gmail.com>
@joshuaunity joshuaunity requested a review from Flix6x March 11, 2026 11:45
@joshuaunity joshuaunity self-assigned this Mar 11, 2026
@joshuaunity joshuaunity added the enhancement New feature or request label Mar 11, 2026
@joshuaunity
Copy link
Contributor Author

CC @nhoening

@read-the-docs-community
Copy link

read-the-docs-community bot commented Mar 11, 2026

Documentation build overview

📚 flexmeasures | 🛠️ Build #31842954 | 📁 Comparing e84899e against latest (547a77b)


🔍 Preview build

Show files changed (55 files in total): 📝 55 modified | ➕ 0 added | ➖ 0 deleted
File Status
changelog.html 📝 modified
configuration.html 📝 modified
genindex.html 📝 modified
_autosummary/flexmeasures.api.common.schemas.assets.html 📝 modified
_autosummary/flexmeasures.api.common.schemas.generic_schemas.html 📝 modified
_autosummary/flexmeasures.api.common.schemas.search.html 📝 modified
_autosummary/flexmeasures.api.common.schemas.sensor_data.html 📝 modified
_autosummary/flexmeasures.api.common.schemas.sensors.html 📝 modified
_autosummary/flexmeasures.api.common.schemas.users.html 📝 modified
_autosummary/flexmeasures.api.common.utils.api_utils.html 📝 modified
_autosummary/flexmeasures.api.v3_0.assets.html 📝 modified
_autosummary/flexmeasures.api.v3_0.sensors.html 📝 modified
_autosummary/flexmeasures.api.v3_0.users.html 📝 modified
_autosummary/flexmeasures.data.models.charts.belief_charts.html 📝 modified
_autosummary/flexmeasures.data.models.data_sources.html 📝 modified
_autosummary/flexmeasures.data.models.forecasting.model_spec_factory.html 📝 modified
_autosummary/flexmeasures.data.models.forecasting.pipelines.base.html 📝 modified
_autosummary/flexmeasures.data.models.forecasting.pipelines.predict.html 📝 modified
_autosummary/flexmeasures.data.models.generic_assets.html 📝 modified
_autosummary/flexmeasures.data.models.planning.html 📝 modified
_autosummary/flexmeasures.data.models.planning.storage.html 📝 modified
_autosummary/flexmeasures.data.models.planning.utils.html 📝 modified
_autosummary/flexmeasures.data.models.time_series.html 📝 modified
_autosummary/flexmeasures.data.schemas.account.html 📝 modified
_autosummary/flexmeasures.data.schemas.attributes.html 📝 modified
_autosummary/flexmeasures.data.schemas.forecasting.html 📝 modified
_autosummary/flexmeasures.data.schemas.forecasting.pipeline.html 📝 modified
_autosummary/flexmeasures.data.schemas.generic_assets.html 📝 modified
_autosummary/flexmeasures.data.schemas.io.html 📝 modified
_autosummary/flexmeasures.data.schemas.reporting.aggregation.html 📝 modified
_autosummary/flexmeasures.data.schemas.reporting.html 📝 modified
_autosummary/flexmeasures.data.schemas.reporting.pandas_reporter.html 📝 modified
_autosummary/flexmeasures.data.schemas.reporting.profit.html 📝 modified
_autosummary/flexmeasures.data.schemas.scheduling.html 📝 modified
_autosummary/flexmeasures.data.schemas.scheduling.metadata.html 📝 modified
_autosummary/flexmeasures.data.schemas.scheduling.process.html 📝 modified
_autosummary/flexmeasures.data.schemas.sensors.html 📝 modified
_autosummary/flexmeasures.data.schemas.sources.html 📝 modified
_autosummary/flexmeasures.data.schemas.times.html 📝 modified
_autosummary/flexmeasures.data.schemas.units.html 📝 modified
_autosummary/flexmeasures.data.schemas.utils.html 📝 modified
_autosummary/flexmeasures.data.services.forecasting.html 📝 modified
_autosummary/flexmeasures.data.services.sensors.html 📝 modified
_autosummary/flexmeasures.data.services.users.html 📝 modified
_autosummary/flexmeasures.ui.utils.breadcrumb_utils.html 📝 modified
_autosummary/flexmeasures.ui.utils.view_utils.html 📝 modified
api/v3_0.html 📝 modified
dev/automated-deploy-via-GHActions.html 📝 modified
dev/ci.html 📝 modified
dev/dependency-management.html 📝 modified
dev/docker-compose.html 📝 modified
dev/setup-and-guidelines.html 📝 modified
host/data.html 📝 modified
plugin/customisation.html 📝 modified
tut/toy-example-setup.html 📝 modified

@Flix6x
Copy link
Contributor

Flix6x commented Mar 11, 2026

Thank you for requesting a review. It looks like the scope of this PR may be mistaken? You are creating an endpoint to copy all assets under a given account*, rather than an endpoint to copy a given asset, including all assets under it.

@nhoening
Copy link
Contributor

We can also discuss the test strategy. Joshua chose to implement a part of the solution, then tests for that, then the next part, test for that etc.

I believe we suggested initially to have one test case that tests a complete successful copy, then work on making it pass.

  • The test can assert the first part first (e.g. assets and subassets are copied), and others later(sensors, flex-config are copied), so you can still follow along how far you are in kaking the test pass, layer by layer.
  • This way would be more helpful in understanding together if the scope is agreed between all of us. The test is easier to write (I suggest using AI to help) and to read than the actual implementation.

"20 \u00b0C",
"3 * 230V * 16A"
]
"description": "Quantity string describing a fixed quantity."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mistake.

Signed-off-by: Joshua Edward <oghenerobojosh01@gmail.com>
@joshuaunity joshuaunity requested a review from Flix6x March 13, 2026 12:03
joshuaunity and others added 2 commits March 13, 2026 17:23
Signed-off-by: Joshua Edward <oghenerobojosh01@gmail.com>
Copy link
Contributor

@Flix6x Flix6x left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @joshuaunity this is now heading in the right direction. See my comments for the next challenge: a deep copy. Just let me know if any decisions come up.

Comment on lines +1605 to +1610
if account is None:
resolved_account = asset.owner
resolved_parent = asset.parent_asset
else:
resolved_account = account
resolved_parent = parent_asset
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this to the @post_load in the schema, too.

assert first_copy.parent_asset_id == parent.id

# Second copy under the same parent fails: UNIQUE(name, parent_asset_id) is violated
# because parent_asset_id is non-NULL (PostgreSQL only treats NULLs as distinct).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostgreSQL only treats NULLs as distinct

Interesting. So when coping twice to a NULL parent, would it be possible to then get two identically named top-level assets?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unique constraint only applies when there is an actual ID. If both assets are without a parent, they will be created without a problem.

Comment on lines +819 to +820
3. flex_context is preserved verbatim (sensor IDs are unchanged).
4. copy_asset is a *shallow* copy: the original child assets are not duplicated.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great to see these kinds of explicit test expectations written up, thanks for that!

Assertions 3 and 4 are the opposite of what we desire, I think. That is, we want the feature to create a deep copy, by making new copies of child assets and new copies of (non-public) sensors anywhere in the underlying asset tree.

@nhoening one thing we haven't explicitly written up is whether the time series data would need to be copied, too. I vote no, to keep the scope at bay.

Signed-off-by: joshuaunity <oghenerobojosh01@gmail.com>
Signed-off-by: joshuaunity <oghenerobojosh01@gmail.com>
},
location="path",
)
@as_json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add a decorator here to check for read access (or whatever we named that) on the asset itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Copying assets

3 participants